﻿#include "command.h"

#include <QString>
#include <QByteArray>
#include <QStack>

#include "hyTool.h"
#include "hyMath.h"
#include "cInit.h"
#include "cInit_hy188d.h"
#include "script.h"

namespace SDHuaYi_Script
{
    using namespace SDHuaYi_Utils;
    command::command()
    {
    }

    bool command::isCmdJudge(QString cmdValue)
    {
        if (cmdValue.contains("==") || cmdValue.contains("!=") || cmdValue.contains(">") || cmdValue.contains("<"))
        {
            return true;
        }
        return false;
    }

    bool command::isCmdSetData(QString cmdValue)
    {
        QRegExp regExp("\\s+");
        cmdValue.replace(regExp,"");
        if (cmdValue.contains("=") == false)
        {
            return false;
        }

        QString preChar = cmdValue.mid(cmdValue.indexOf('=') - 1, 1);
        QString nextChar = QString();
        if (cmdValue.count() > cmdValue.indexOf('=') + 2)
        {
            nextChar = cmdValue.mid((cmdValue.indexOf('=') + 1), 1);
        }
        if ((preChar == "!") || (preChar == ">") || (preChar == "<"))
        {
            return false;
        }
        if (nextChar == "=")
        {
            return false;
        }
        return true;
    }

    void command::MathProcess(QString &cmdValue)
    {
        if (cmdValue.contains("+") || cmdValue.contains("-") || cmdValue.contains("*") || cmdValue.contains("/"))
        {
            QStringList datas = cmdValue.split(QRegExp("\\s+"), QString::SkipEmptyParts);

            cmdValue.clear();
            for (int i = 0; i < datas.count(); i++)
            {
                if(!isOpr(datas[i]))
                {
                    datas[i] = FormatToDataInteger(datas[i]);
                }
                cmdValue += datas[i];
            }

            QByteArray array = cmdValue.replace("#","").toUtf8();
            HYMath math = HYMath();
            for(int i = 0;i<array.count();i++)
            {
                char element = array[i];
                math.inputStr.append(element);
            }
            cmdValue = "#"+math.DataMain();
        }
    }

    QString command::Excute(QString cmdValue, QList<Para> &paras, HY_RSA_PUBLIC_KEY hY_RSA_PUBLIC_KEY)
    {
        this->hY_RSA_PUBLIC_KEY = hY_RSA_PUBLIC_KEY;
        bool isCmdSetdata = false;
        bool isShowData = false;

        if (cmdValue.contains("?"))
        {
            cmdValue = cmdValue.mid(cmdValue.indexOf("?") + 1);
            isShowData = true;
        }

        QString cmdLeft = QString();
        if (isCmdSetData(cmdValue))
        {
            cmdLeft = cmdValue.mid(0, cmdValue.indexOf('=') + 1) + " ";
            cmdValue = cmdValue.mid(cmdValue.indexOf('=') + 1);
            isCmdSetdata = true;
        }

        if (isCmdJudge(cmdValue))
        {
            QString code = QString();
            QString cmdJudgeLeft = QString();
            QString cmdJudgeRight = QString();

            if (cmdValue.contains("=="))
            {
                code = "==";
                cmdJudgeLeft = cmdValue.mid(0, cmdValue.indexOf("=")).trimmed();
                cmdJudgeRight = cmdValue.mid(cmdValue.lastIndexOf("=") + 1).trimmed();
            }
            else if (cmdValue.contains("="))
            {
                code = cmdValue.mid(cmdValue.indexOf("=") - 1, 2);
                cmdJudgeLeft = cmdValue.mid(0, cmdValue.indexOf("=") - 1).trimmed();
                cmdJudgeRight = cmdValue.mid(cmdValue.indexOf("=") + 1).trimmed();
            }
            else
            {
                if (cmdValue.contains(">"))
                {
                    code = ">";
                    cmdJudgeLeft = cmdValue.mid(0, cmdValue.indexOf(">")).trimmed();
                    cmdJudgeRight = cmdValue.mid(cmdValue.indexOf(">") + 1).trimmed();
                }
                else
                {
                    code = "<";
                    cmdJudgeLeft = cmdValue.mid(0, cmdValue.indexOf("<")).trimmed();
                    cmdJudgeRight = cmdValue.mid(cmdValue.indexOf("<") + 1).trimmed();
                }
            }

            // 分别处理等式的左右两边
            cmdJudgeLeft = Excute(cmdJudgeLeft, paras).trimmed();
            cmdJudgeRight = Excute(cmdJudgeRight, paras).trimmed();

            if (code == "==")
            {
                if (HYString::stringCompare(cmdJudgeLeft, cmdJudgeRight) == 0)
                {
                    return "true";
                }
                return "false";
            }
            else if (code == ">=")
            {
                if (HYString::stringCompare(cmdJudgeLeft, cmdJudgeRight) >= 0)
                {
                    return "true";
                }
                return "false";
            }
            else if (code == "<=")
            {
                if (HYString::stringCompare(cmdJudgeLeft, cmdJudgeRight) <= 0)
                {
                    return "true";
                }
                return "false";
            }
            else if (code == ">")
            {
                if (HYString::stringCompare(cmdJudgeLeft, cmdJudgeRight) == 1)
                {
                    return "true";
                }
                return "false";
            }
            else if (code == "<")
            {
                if (HYString::stringCompare(cmdJudgeLeft, cmdJudgeRight) == -1)
                {
                    return "true";
                }
                return "false";
            }
            else if (code == "!=")
            {
                if (HYString::stringCompare(cmdJudgeLeft, cmdJudgeRight) != 0)
                {
                    return "true";
                }
                return "false";
            }
        }

        try
        {
            // 规范格式
            Format(cmdValue);

            // 替换语句中的变量
            Assignment(cmdValue, paras);

            // 处理括号以及系统函数
            BracketMatch(cmdValue);

            // 处理数学运算
            MathProcess(cmdValue);

            // 处理赋值语句
            if (isCmdSetdata)
            {
                if (cmdLeft.toUpper().startsWith("S") && cmdValue.trimmed().startsWith("#"))
                {
                    // 整形转换为16进制字符串类型
                    cmdValue = ITOA_Process(cmdValue);
                }
                cmdValue = cmdLeft + cmdValue;

                Equals_Process(cmdValue, paras);

                if (isShowData)
                {
                    return cmdValue;
                }
                return nullptr;
            }
            else
            {
                return cmdValue;
            }
        }
        catch (...)
        {
            throw std::runtime_error("命令格式错误");
        }
    }

    QString command::Excute(cardReaderDev inputReader, QList<Para>& paras, HY_RSA_PUBLIC_KEY hY_RSA_PUBLIC_KEY)
    {
        qint32 st = 0;
        QString sCMD = this->Value;
        this->m_Reader = inputReader;
        this->hY_RSA_PUBLIC_KEY = hY_RSA_PUBLIC_KEY;

        if (m_Reader.readerType == READER_HY3M3)
        {
            // TODO:不兼容此读卡器
        }
        else
        {
            if (sCMD.toUpper().contains("_P"))
            {
                st = Process_Excu(paras, sCMD);
                sLOG = "|Command:" + sCMD + "|SW:" + SW;
                if (st == 0)
                {
                    return sCMD;
                }
            }

            try
            {
                // 规范格式
                Format(sCMD);

                // 替换语句中的变量
                st = Assignment(sCMD, paras);
                if (st != 0)
                {
                    return sCMD;
                }

                // 处理括号和关键字
                st = BracketMatch(sCMD);
                if (st != 0)
                {
                    return sCMD;
                }
            }
            catch (...)
            {
                throw std::runtime_error("命令格式错误");
            }
        }
        bool bRestSuccess = false;
        if (sCMD.trimmed().toUpper() == "INSERT")
        {
            if (!m_Reader.CardReset())
            {
                // 执行10次复位
                for (qint32 iResetNum = 0; iResetNum < 10; iResetNum++)
                {
                    if (m_Reader.CardReset())
                    {
                        bRestSuccess = true;
                        break;
                    }
                }
                // 仍未成功
                if (!bRestSuccess)
                {
                    sLOG += "复位失败";
                    throw std::runtime_error("复位失败");
                }
            }
            else
            {
                sLOG += "|Command:" + sCMD + "|ATS:" + m_Reader.Card.strATS;
                sCMD += "\r\n" + m_Reader.Card.strATS;
                this->Response = m_Reader.Card.strATS;
                Para para1 = Para("RESPONSE", m_Reader.Card.strATS);
                BOP.ParaUpdate(paras, para1);
            }
        }
        else if (sCMD.trimmed().toUpper() == "EJECT")
        {
        }
        else
        {
            // 普通指令
            if (sCMD.replace(" ", "") == "")
                return sCMD;           // 如果指令为空返回
            SendAPDU(sCMD, paras, ""); // 由上层调用判断返回值是否满足预期
            Para para1 = Para("LAST", m_Reader.Response());
            BOP.ParaUpdate(paras, para1);
            para1 = Para("SW", m_Reader.SS());
            BOP.ParaUpdate(paras, para1);
        }
        return sCMD;
    }

    qint32 command::Process_Excu(QList<Para> &paras, QString sCMD)
    {
        qint32 st = 0;
        CInit *cInit = nullptr;

        bool bFLG = false;
        // TODO:此处未做原有指令的兼容
        if (sCMD.replace(" ", "") == "HY188D_BackToDL_P()")
        {
            cInit = new COSInit188D();
            cInit->iReader = m_Reader;
            cInit->iAlgType = HYALG_3DES;
            cInit->BackToDl();
            this->SW = "9000";
        }
        else if (sCMD.replace(" ", "") == "HY188D_DLAuth_P()")
        {
            cInit = new COSInit188D();
            cInit->iReader = m_Reader;
            cInit->iAlgType = HYALG_SM4;
            cInit->DlAuth();
            this->SW = "9000";
        }
        else if (sCMD.replace(" ", "") == "HY188D_Write_P()")
        {
            QString message;
            cInit = new COSInit188D();
            cInit->iReader = m_Reader;
            cInit->iAlgType = HYALG_3DES;
            cInit->cosDownLoad(message);
            this->SW = "9000";
        }
        else if (sCMD.replace(" ", "") == "HY188D_FlashReset_P()")
        {
            cInit = new COSInit188D();
            cInit->iReader = m_Reader;
            cInit->iAlgType = HYALG_3DES;
            cInit->FlashReset();
            this->SW = "9000";
        }
        else if (sCMD.replace(" ", "") == "HY188D_UserInit_P()")
        {
            cInit = new COSInit188D();
            cInit->iReader = m_Reader;
            cInit->iAlgType = HYALG_3DES;
            cInit->cosConfig(updataNewUid, sAuth);
            this->SW = "9000";
        }
        else if (sCMD.replace(" ", "") == "HY188D_Insert_P()")
        {
            cInit = new COSInit188D();
            cInit->iReader = m_Reader;
            cInit->iAlgType = HYALG_3DES;
            cInit->ResetCheck(updataNewUid);
            this->SW = "9000";
        }
        else
        {
            st = -1;
        }

        delete cInit;
        cInit = nullptr;
        return st;
    }

    // 格式处理
    void command::Format(QString &sCMD)
    {
        try
        {
            // 在括号前后加上空格，方便后续处理
            // 数学运算符因为与普通的关键字运算不同，多加一个空格
            sCMD.replace("(", " ( ");
            sCMD.replace(")", " ) ");
            sCMD.replace(",", " , ");
            sCMD.replace("=", " = ");
            sCMD.replace("+", " + ");
            sCMD.replace("-", " - ");
            sCMD.replace("*", " * ");
            sCMD.replace("/", " / ");
            sCMD.replace("(", " ( ");
            sCMD.replace(")", " ) ");
        }
        catch (...)
        {
            throw std::runtime_error("格式化字符串异常");
        }
    }

    qint32 command::BracketMatch(QString &sCMD)
    {
        qint32 st = 0;
        if (sCMD.isEmpty() || sCMD.isNull())
        {
            st = -1;
            return st;
        }
        QStack<QChar> stack = {};
        QStack<qint32> stackIndex = {};
        QString sKHQ = {};

        for (int i = 0; i < sCMD.count(); i++)
        {

            if (sCMD[i] == '(')
            {
                stack.push(sCMD[i]); // 左括号入栈
                stackIndex.push(i);  // 左括号索引入栈
            }
            else if (sCMD[i] == ")")
            {
                if (stack.count() == 0)
                {
                    st = -1;
                    return st;
                }
                else
                {
                    QChar left = stack.top(); // 访问左括号的栈顶值
                    stack.pop();              // 出栈顶值
                    qint32 idex = stackIndex.pop();

                    // 组织计算
                    QString sCMDLF = sCMD.mid(0, idex);
                    // 寻找关键字
                    QStringList tmp = sCMDLF.split(QRegExp("\\s+"), QString::SkipEmptyParts);
                    QString sKHN = sCMD.mid(idex + 1, i - idex - 1);
                    QStringList sPara = sKHN.split(',', QString::SkipEmptyParts);
                    QString sRes = QString();

                    // 公式计算
                    if (tmp.count() > 0)
                    {
                        for (int j = 0; j < sPara.count(); j++)
                        {
                            MathProcess(sPara[j]);
                        }

                        sRes = KeyWordTable(tmp[tmp.count() - 1], sPara);
                        if (tmp[tmp.count() - 1] == "+" || tmp[tmp.count() - 1] == "-" || tmp[tmp.count() - 1] == "*" || tmp[tmp.count() - 1] == "/")
                        {
                            sCMD = sCMDLF.mid(0, sCMDLF.lastIndexOf(tmp[tmp.count() - 1])) + sRes + " " + sCMD.mid(i + 1, sCMD.count() - i - 1);
                        }
                        else
                        {
                            if (tmp[tmp.count() - 1].replace(" ", "") == ",")
                            {
                                // 对于多余括号的处理流程
                                sCMD = sCMDLF.mid(0, sCMDLF.lastIndexOf(tmp[tmp.count() - 1])) + "," + sRes + " " + sCMD.mid(i + 1, sCMD.count() - i - 1);
                            }
                            else
                            {
                                sCMD = sCMDLF.mid(0, sCMDLF.lastIndexOf(tmp[tmp.count() - 1])) + sRes + " " + sCMD.mid(i + 1, sCMD.count() - i - 1);
                            }
                        }
                        i = sCMDLF.lastIndexOf(tmp[tmp.count() - 1]) + sRes.count();
                    }
                    else
                    {
                        // 不含关键字的括号运算，去掉括号，进入数学计算流程处理
                        sCMD = sCMD.replace("(", "");
                        sCMD = sCMD.replace(")", "");
                        Format(sCMD);
                        MathProcess(sCMD);
                    }
                }
            }
            else
            {
                //
            }
        }
        return st;
    }

    QString command::KeyWordTable(QString sCmdHeader, QStringList sPara)
    {
        QString sRes = {};

        try
        {
            sCmdHeader = sCmdHeader.replace(" ", "").toUpper();
            if (sCmdHeader.startsWith("?"))
            {
                sCmdHeader = sCmdHeader.mid(1, sCmdHeader.count() - 1); // 如果有问号，则判断问号后面的部分
            }

            if (sCmdHeader == "DATA_ENC")
            {
                if (sPara.count() > 1)
                {
                    sRes = DATA_ENC_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "DATA_DEC")
            {
                if (sPara.count() > 1)
                {
                    sRes = DATA_DEC_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "DEC")
            {
                if (sPara.count() > 1)
                {
                    sRes = DEC_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "ENC")
            {
                if (sPara.count() > 1)
                {
                    sRes = ENC_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "MAC")
            {
                // 假定Mac计算需要三个参数都存在
                if (sPara.count() == 3)
                {
                    sRes = MAC_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""), sPara[2].replace(" ", ""));
                }
                else if (sPara.count() == 2)
                {
                    sRes = MAC_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""), "0000000000000000");
                }
            }
            else if (sCmdHeader == "STRXOR")
            {
                if (sPara.count() > 1)
                {
                    sRes = STRXOR_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "STROR")
            {
                if (sPara.count() > 1)
                {
                    sRes = STROR_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "STRADD")
            {
                if (sPara.count() > 1)
                {
                    sRes = STRADD_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "STRSUB")
            {
                if (sPara.count() > 1)
                {
                    sRes = STRSUB_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "STRAND")
            {
                if (sPara.count() > 1)
                {
                    sRes = STRAND_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "MID")
            {
                if (sPara.count() > 2)
                {
                    sRes = Mid_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""), sPara[2].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "LEFT")
            {
                if (sPara.count() > 1)
                {
                    sRes = Left_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "RIGHT")
            {
                if (sPara.count() > 1)
                {

                    sRes = Right_Process(sPara[0].replace(" ", ""), sPara[1].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "LEN")
            {
                if (sPara.count() > 0)
                {
                    qint32 tc = Len_Process(sPara[0].replace(" ", ""));
                    sRes = "#" + QString::number(tc);
                }
            }
            else if (sCmdHeader == "INVERSE")
            {
                if (sPara.count() > 0)
                {
                    sRes = INVERSE_Process(sPara[0].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "XOR")
            {
                if (sPara.count() > 0)
                {
                    sRes = XOR_Process(sPara[0].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "ITOA")
            {
                if (sPara.count() > 0)
                {
                    sRes = ITOA_Process(sPara[0].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "ATOI")
            {
                if (sPara.count() > 0)
                {
                    sRes = ATOI_Process(sPara[0].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "/")
            {
                if (sPara.count() > 0)
                {
                    sRes = (sPara[0]);
                    MathProcess(sRes);
                }
            }
            else if (sCmdHeader == "*")
            {
                if (sPara.count() > 0)
                {
                    sRes = (sPara[0]);
                    MathProcess(sRes);
                }
            }
            else if (sCmdHeader == "+")
            {
                if (sPara.count() > 0)
                {
                    sRes = (sPara[0]);
                    MathProcess(sRes);
                }
            }
            else if (sCmdHeader == "-")
            {
                if (sPara.count() > 0)
                {
                    sRes = (sPara[0]);
                    MathProcess(sRes);
                }
            }
            else if (sCmdHeader == "DLAUTH")
            {
            }
            else if (sCmdHeader == "RSA_PUB_ENC")
            {
                if (sPara.count() > 0)
                {
                    sRes = RSA_PUB_ENC_Process(sPara[0]);
                }
            }
            else if (sCmdHeader == "PKSET")
            {
                if (sPara.count() > 0)
                {
                    RSA_PUBKEY_SET_Process(sPara[0]);
                }
            }
            else if (sCmdHeader == "PKEXP")
            {
                if (sPara.count() > 0)
                {
                    RSA_PUBEXP_SET_Process(sPara[0]);
                }
            }
            else if (sCmdHeader == "SM4_ENC")
            {
                if (sPara.count() > 0)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_ECB, ALG_ENC, sPara[1].replace(" ", ""), nullptr, sPara[0].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "SM4_DEC")
            {
                if (sPara.count() > 0)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_ECB, ALG_DEC, sPara[1].replace(" ", ""), nullptr, sPara[0].replace(" ", ""));
                }
            }
            else if (sCmdHeader == "SM4_MAC")
            {
                if (sPara.count() == 2)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_MAC, ALG_DEC, sPara[1].replace(" ", ""), "00000000000000000000000000000000", sPara[0].replace(" ", ""));
                    sRes.mid(0, 8);
                }
                else if (sPara.count() == 3)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_MAC, ALG_DEC, sPara[1].replace(" ", ""), sPara[2].replace(" ", ""), sPara[0].replace(" ", ""));
                    sRes.mid(0, 8);
                }
            }
            else if (sCmdHeader == "SM4_MACX")
            {
                if (sPara.count() == 2)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_MAC, ALG_DEC, sPara[1].replace(" ", ""), "00000000000000000000000000000000", sPara[0].replace(" ", ""));
                    QString str = sRes.mid(0, 16);
                    QString str2 = sRes.mid(16, 16);
                    QString str3 = HYString::strxor(str, str2);
                    sRes = str3.mid(0, 8);
                }
                else if (sPara.count() == 3)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_MAC, ALG_DEC, sPara[1].replace(" ", ""), sPara[2].replace(" ", ""), sPara[0].replace(" ", ""));
                    QString str = sRes.mid(0, 16);
                    QString str2 = sRes.mid(16, 16);
                    QString str3 = HYString::strxor(str, str2);
                    sRes = str3.mid(0, 8);
                }
            }
            else if (sCmdHeader == "SM4_MACX_4")
            { // 4个字节为单位异或运算，取最后的四字节为结果
                if (sPara.count() == 2)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_MAC, ALG_DEC, sPara[1].replace(" ", ""), "00000000000000000000000000000000", sPara[0].replace(" ", ""));
                    QString str = sRes.mid(0, 8);
                    for (int k = 0; k < 3; k++)
                    {
                        str = HYString::strxor(str, sRes.mid((k + 1) * 8, 8));
                    }
                    sRes = str;
                }
                else if (sPara.count() == 3)
                {
                    sRes = HYALG_SM4Crypt(ALG_MODE_MAC, ALG_DEC, sPara[1].replace(" ", ""), sPara[2].replace(" ", ""), sPara[0].replace(" ", ""));
                    QString str = sRes.mid(0, 8);
                    for (int k = 0; k < 3; k++)
                    {
                        str = HYString::strxor(str, sRes.mid((k + 1) * 8, 8));
                    }
                    sRes = str;
                }
            }
            else
            {
                // 对于不能识别的指令返回第一个字段值
                if (sPara.count() > 0)
                {
                    sRes = sPara[0];
                }
            }
        }
        catch (...)
        {
            throw std::runtime_error("关键字分析异常");

        }
        return sRes;
    }

    bool command::isOpr(QString oper)
    {
        if (oper.trimmed() == "+")
        {
            return true;
        }
        if (oper.trimmed() == "-")
        {
            return true;
        }
        if (oper.trimmed() == "*")
        {
            return true;
        }
        if (oper.trimmed() == "/")
        {
            return true;
        }
        if (oper.trimmed() == "(")
        {
            return true;
        }
        if (oper.trimmed() == ")")
        {
            return true;
        }
        return false;
    }

    QString command::FormatToDataInteger(QString data)
    {
        QByteArray charArr = data.toUtf8();
        if (data.mid(1).contains("#"))
        {
            throw std::runtime_error("表达式格式错误");
        }
        if (charArr[0] == '#')
        {
            return data; // 立即数
        }
        else
        {
            //            qint32 num = HYString::string2int(data);
            return "#" + QString::number(HYString::string2int(data));
        }
    }

    bool command::IntegerReplace(QString &str)
    {
        QString temp = str.trimmed();
        if (temp == "")
            return true;
        if (temp.mid(0, 1) != "#")
        {
            return false;
        }
        if (temp.mid(1).contains("#"))
        {
            throw std::runtime_error("命令格式解析错误");
        }
        bool OK;
        qint32 data = temp.mid(1).toInt(&OK);
        if (OK == false)
        {
            return false;
            // throw std::runtime_error("字符转数字出错");
        }

        // 取两位整数
        str = HYString::int2string(data, 2);

        return true;
    }

    qint32 command::Assignment(QString &sDataIn, QList<Para> &para)
    {
        if (sDataIn == "NO RESPONSE")
            return 0;
        qint32 st = 0;
        // 使用空格隔开
        QStringList cmds = sDataIn.split(QRegExp("\\s+"), QString::SkipEmptyParts);

        sDataIn.clear();

        for (qint32 i = 0; i < cmds.count(); i++)
        {
            if (!isOpr(cmds[i]))
            {
                if (false == (IntegerReplace(cmds[i])))
                {
                    // 从参数列表中获取
                    cmds[i] = BOP.ParaQuery(para, cmds[i]);
                }
            }
            sDataIn += cmds[i] + " ";
        }
        return st;
    }

    void command::Equals_Process(QString sDataIn, QList<Para> &para)
    {
        QRegExp regExp("\\s+");
        QStringList cmds = sDataIn.replace(regExp,"").split('=', QString::SkipEmptyParts);
        // cmds.removeAll(" ");//sDataIn.split(QRegExp("\\s+"));
        if (!sDataIn.contains("(")) // 如果赋值语句不含公式计算
        {
            if (cmds.count() == 2)
            {
                Para para1 = Para(cmds[0].trimmed(), cmds[1]);
                BOP.ParaUpdate(para, para1);
            }
        }
    }

    QString command::DATA_ENC_Process(QString value, QString key)
    {
        QString sRes = QString();
        int Keylen = key.count();

        if (Keylen != 16 && Keylen != 32)
        {
            if (Keylen < 16)
            {
                for (int i = 0; i < 16 - Keylen; i++)
                {
                    key = key + '0';
                }
            }
            else if (Keylen < 16 && Keylen < 32)
            {
                for (int i = 0; i < 32 - Keylen; i++)
                {
                    key = key + '0';
                }
            }
        }

        int slen = value.count();
        int mod16 = slen % 16;

        QString stmp = QString::number(slen / 2, 16).toUpper();
        if (stmp.count() % 2 != 0)
        {
            stmp = "0" + stmp;
        }
        value = stmp + value; // 源数据前加上数据长度
        slen = value.count();
        mod16 = slen % 16;
        // 如果长度恰好是7字节的话，加8000000000000000
        if (stmp == "07")
        {
            value = value + "8000000000000000";
        }
        else
        {
            value = value + QString("8000000000000000").mid(0, 16 - mod16);
        }

        sRes = HYALG_DESCrypt(ALG_MODE_ECB, ALG_ENC, key, nullptr, value);
        return sRes;
    }

    QString command::DATA_DEC_Process(QString value, QString key)
    {
        QString sDec = QString();
        int keyLen = key.count();

        if (keyLen != 16 && keyLen != 32)
        {
            if (keyLen < 16)
            {
                for (int i = 0; i < 16 - keyLen; i++)
                {
                    key = key + '0';
                }
            }
            else if (keyLen < 16 && keyLen < 32)
            {
                for (int i = 0; i < 32 - keyLen; i++)
                {
                    key = key + '0';
                }
            }
        }
        keyLen = key.count();

        sDec = HYALG_DESCrypt(ALG_MODE_ECB, ALG_DEC, key, nullptr, value);
        return sDec;
    }

    QString command::ENC_Process(QString value, QString key)
    {
        QString sEnc = QString();
        int valueLen = value.count();
        int keyLen = key.count();

        if (valueLen > 16)
        {
            value = value.mid(0, 16);
        }
        else if (valueLen < 16)
        {
            for (int i = 0; i < 16 - valueLen; i++)
            {
                value = "0" + value;
            }
        }

        valueLen = value.count();

        if (keyLen != 16 && keyLen != 32)
        {
            if (keyLen < 16)
            {
                for (int i = 0; i < 16 - keyLen; i++)
                {
                    key = key + '0';
                }
            }
            else if (keyLen < 16 && keyLen < 32)
            {
                for (int i = 0; i < 32 - keyLen; i++)
                {
                    key = key + '0';
                }
            }
        }
        keyLen = key.count();

        sEnc = HYALG_DESCrypt(ALG_MODE_ECB, ALG_ENC, key, nullptr, value);
        sEnc = sEnc.mid(0, valueLen);

        return sEnc;
    }

    QString command::DEC_Process(QString value, QString key)
    {
        QString sDec = QString();
        int keyLen = key.count();
        int valueLen = value.count();

        if (keyLen != 16 && keyLen != 32)
        {
            if (keyLen < 16)
            {
                for (int i = 0; i < 16 - keyLen; i++)
                {
                    key = key + '0';
                }
            }
            else if (keyLen < 16 && keyLen < 32)
            {
                for (int i = 0; i < 32 - keyLen; i++)
                {
                    key = key + '0';
                }
            }
        }
        keyLen = key.count();

        sDec = HYALG_DESCrypt(ALG_MODE_ECB, ALG_DEC, key, nullptr, value);
        sDec = sDec.mid(0, valueLen);

        return sDec;
    }

    QString command::MAC_Process(QString value, QString key, QString challange)
    {
        QString sMac;
        sMac = HYALG_DESCrypt(ALG_MODE_MAC, ALG_ENC, key, challange, value);
        return sMac;
    }

    QString command::RSA_PUB_ENC_Process(QString sInPutData)
    {
        // TODO:暂缓实现
        qDebug() << __FILE__ << __func__ << __LINE__ << ":此函数尚未实现";
        return "error";
    }

    qint32 command::RSA_PUBKEY_SET_Process(QString sInPutData)
    {
        // TODO:暂缓实现
        qDebug() << __FILE__ << __func__ << __LINE__ << ":此函数尚未实现";
        return -1;
    }

    qint32 command::RSA_PUBEXP_SET_Process(QString sInPutData)
    {
        // TODO:暂缓实现
        qDebug() << __FILE__ << __func__ << __LINE__ << ":此函数尚未实现";
        return -1;
    }

    QString command::Mid_Process(QString sDataIn, QString sStart, QString sLen)
    {
        int iStart = 0;
        int iLen = 0;
        sStart = sStart.replace("#", "");
        sLen = sLen.replace("#", "");
        bool ok;

        iStart = sStart.toInt(&ok);
        if (!ok)
        {
            throw std::runtime_error("截取字符串，起始位置异常");
        }

        iLen = sLen.toInt(&ok);
        if (!ok)
        {
            throw std::runtime_error("截取字符串，长度异常");
        }

        QString sMid = QString();
        if (iStart > sDataIn.count())
        {
            sMid = "";
        }
        else
        {
            sMid = sDataIn.mid(iStart - 1, iLen);
        }
        return sMid;
    }

    QString command::Left_Process(QString sDataIn, QString sLen)
    {
        bool ok;
        sLen = sLen.replace("#", "");
        int iLen = sLen.toInt(&ok);
        if (!ok)
        {
            throw std::runtime_error("左取字符串，长度异常");
        }
        try
        {
            return sDataIn.mid(0, iLen);
        }
        catch (...)
        {
            throw std::runtime_error("左取字符串异常");
        }
    }

    QString command::Right_Process(QString sDataIn, QString sLen)
    {
        int iLen = 0;
        bool ok;
        sLen = sLen.replace("#", "").replace(" ", "");
        iLen = sLen.toInt(&ok);
        if (!ok)
        {
            throw std::runtime_error("右取字符串，长度异常");
        }

        try
        {
            return sDataIn.mid(sDataIn.count() - iLen, iLen);
        }
        catch (...)
        {
            throw std::runtime_error("右取字符串异常");
        }
    }

    qint32 command::Len_Process(QString sDataIn)
    {
        try
        {
            return sDataIn.count();
        }
        catch (...)
        {
            throw std::runtime_error("计算字符串长度异常");
        }
    }

    QString command::STRXOR_Process(QString sDataIn1, QString sDataIn2)
    {
        QString sDataOut = QString();
        try
        {
            QByteArray para1 = BOP.StrToHexByte(sDataIn1);
            QByteArray para2 = BOP.StrToHexByte(sDataIn2);
            int iLen1 = sDataIn1.count() / 2;
            int iLen2 = sDataIn2.count() / 2;
            int iLen = 0;

            if (iLen1 < iLen2)
            {
                iLen = iLen1;
                sDataOut += sDataIn2.mid(0, iLen2 * 2 - iLen * 2);
            }
            else
            {
                iLen = iLen2;
                sDataOut += sDataIn1.mid(0, iLen1 * 2 - iLen * 2);
            }

            QByteArray res(iLen, 0);
            for (int i = iLen; i > 0; i--)
            {
                res[iLen - i] = (para1[iLen1 - i] ^ para2[iLen2 - i]);
                sDataOut += QString("%1").arg(static_cast<int>(res[iLen - i]), 2, 16, QLatin1Char('0')).toUpper();
            }
        }
        catch (...)
        {
            throw std::runtime_error("字符串异或异常");
        }
        return sDataOut;
    }

    QString command::STROR_Process(QString sDataIn1, QString sDataIn2)
    {
        QString sDataOut = QString();
        try
        {
            QByteArray para1 = BOP.StrToHexByte(sDataIn1);
            QByteArray para2 = BOP.StrToHexByte(sDataIn2);
            int iLen1 = sDataIn1.count() / 2;
            int iLen2 = sDataIn2.count() / 2;
            int iLen = 0;

            if (iLen1 < iLen2)
            {
                iLen = iLen1;
                sDataOut += sDataIn2.mid(0, iLen2 * 2 - iLen * 2);
            }
            else
            {
                iLen = iLen2;
                sDataOut += sDataIn1.mid(0, iLen1 * 2 - iLen * 2);
            }

            QByteArray res(iLen, 0);
            for (int i = iLen; i > 0; i--)
            {
                res[iLen - i] = (para1[iLen1 - i] | para2[iLen2 - i]);
                sDataOut += QString("%1").arg(static_cast<int>(res[iLen - i]), 2, 16, QLatin1Char('0')).toUpper();
            }
        }
        catch (...)
        {
            throw std::runtime_error("字符串或异常");
        }
        return sDataOut;
    }

    QString command::STRAND_Process(QString sDataIn1, QString sDataIn2)
    {
        QString sDataOut = QString();
        try
        {
            QByteArray para1 = BOP.StrToHexByte(sDataIn1);
            QByteArray para2 = BOP.StrToHexByte(sDataIn2);
            int iLen1 = sDataIn1.count() / 2;
            int iLen2 = sDataIn2.count() / 2;
            int iLen = 0;

            if (iLen1 < iLen2)
            {
                iLen = iLen1;
                sDataOut += sDataIn2.mid(0, iLen2 * 2 - iLen * 2);
            }
            else
            {
                iLen = iLen2;
                sDataOut += sDataIn1.mid(0, iLen1 * 2 - iLen * 2);
            }

            QByteArray res(iLen, 0);
            for (int i = iLen; i > 0; i--)
            {
                res[iLen - i] = (para1[iLen1 - i] & para2[iLen2 - i]);
                sDataOut += QString("%1").arg(static_cast<int>(res[iLen - i]), 2, 16, QLatin1Char('0')).toUpper();
            }
        }
        catch (...)
        {
            throw std::runtime_error("字符串与异常");
        }
        return sDataOut;
    }

    QString command::STRADD_Process(QString sDataIn1, QString sDataIn2)
    {
        QString optr1 = QString();
        QString optr2 = QString();
        if (sDataIn1.count() % 2 != 0)
        {
            sDataIn1 = "0" + sDataIn1;
        }
        if (sDataIn2.count() % 2 != 0)
        {
            sDataIn2 = "0" + sDataIn2;
        }
        if (sDataIn1.count() < sDataIn2.count())
        {
            optr1 = sDataIn2;
            optr2 = sDataIn1;
        }
        optr1 = sDataIn1;
        optr2 = sDataIn2;
        int i = 0;
        for (i = 0; i < sDataIn1.count() / 2 - sDataIn2.count() / 2; i++)
        {
            // 补00
            optr2 = "00" + optr2;
        }
        QByteArray bstr1(optr1.count() / 2, 0);
        QByteArray bstr2(optr2.count() / 2, 0);
        HYString::string2byteArray(optr1, bstr1);
        HYString::string2byteArray(optr2, bstr2);

        char c_byte = 0;

        for (i = bstr1.count() - 1; i >= 0; i--)
        {
            short result = static_cast<short>(static_cast<short>(bstr1[i]) + static_cast<short>(bstr2[i]) + c_byte);
            if (result > 0xFF)
            {
                c_byte = 1;
            }

            bstr1[i] = static_cast<char>(result & 0xFF);
        }

        return HYString::byteArray2String(bstr1, bstr1.count());
    }

    QString command::STRSUB_Process(QString sDataIn1, QString sDataIn2)
    {
        QString optr1 = "";
        QString optr2 = "";
        if (sDataIn1.count() % 2 != 0)
        {
            sDataIn1 = "0" + sDataIn1;
        }
        if (sDataIn2.count() % 2 != 0)
        {
            sDataIn2 = "0" + sDataIn2;
        }
        if (sDataIn1.count() < sDataIn2.count())
        {
            optr1 = sDataIn2;
            optr2 = sDataIn1;
        }
        optr1 = sDataIn1;
        optr2 = sDataIn2;
        int i = 0;
        for (i = 0; i < sDataIn1.count() / 2 - sDataIn2.count() / 2; i++)
        {
            // 补00
            optr2 = "00" + optr2;
        }

        QByteArray bstr1(optr1.count() / 2, 0);
        QByteArray bstr2(optr2.count() / 2, 0);

        HYString::string2byteArray(optr1, bstr1);
        HYString::string2byteArray(optr2, bstr2);

        char c_byte = 0;

        for (i = bstr1.count() - 1; i >= 0; i--)
        {
            short result = static_cast<short>(static_cast<short>(bstr1[i]) - static_cast<short>(bstr2[i]) + c_byte);
            if (result > 0xFF)
            {
                c_byte = 1;
            }

            bstr1[i] = static_cast<char>(result & 0xFF);
        }

        return HYString::byteArray2String(bstr1, bstr1.count());
    }

    QString command::INVERSE_Process(QString sDataIn)
    {
        QString sResult = "";
        try
        {
            QByteArray rs = BOP.StrToHexByte(sDataIn);

            QByteArray result(rs.count(), 0);

            for (int i = 0; i < sDataIn.count() / 2; i++)
            {
                result[i] = static_cast<char>(~rs[i]);
                // TODO:此处处理0时为何会变为4字节
                sResult += QString("%1").arg(static_cast<int>(result[i]), 2, 16, QLatin1Char('0')).toUpper();
            }
        }
        catch (...)
        {
            throw std::runtime_error("字符串取反错");
        }
        return sResult;
    }

    QString command::XOR_Process(QString sDateIn)
    {
        QString sRes = "";
        int iRes = 0;
        try
        {
            QByteArray sdata(sDateIn.count() / 2, 0);
            sdata = BOP.StrToHexByte(sDateIn);
            if (sdata.count() > 1)
            {
                iRes = sdata[0];
                for (int i = 1; i < sdata.count(); i++)
                {
                    iRes = iRes ^ sdata[i];
                }
                sRes = QString("%1").arg(iRes, 2, 16, QLatin1Char('0')).toUpper();
            }
        }
        catch (...)
        {
            throw std::runtime_error("计算字节字符串(16进制数)异或值错误");
        }
        return sRes;
    }

    QString command::ITOA_Process(QString sDataIn)
    {
        try
        {
            if (sDataIn.contains("#"))
            {
                // 10进制数转16进制字符串
                sDataIn = sDataIn.mid(sDataIn.indexOf("#") + 1);
                qint32 iData = sDataIn.toInt();
                sDataIn = QString::number(iData, 16).toUpper();
            }
            // 补位
            if (sDataIn.count() % 2 != 0)
            {
                sDataIn = "0" + sDataIn;
            }
        }
        catch (...)
        {
            throw std::runtime_error("整形数值转16进制错误");
        }
        return sDataIn;
    }

    QString command::ATOI_Process(QString sDataIn)
    {
        try
        {
            if (!sDataIn.contains("#"))
            {
                // 16进制数转10进制字符串
                bool OK;
                qint32 iData = sDataIn.toInt(&OK, 16);
                sDataIn = "#" + QString::number(iData);
            }
        }
        catch (...)
        {
//            throw std::runtime_error("16进制转整形数值错误");
            throw std::runtime_error("16");
        }
        return sDataIn;
    }

    void command::SendAPDU(QString sCMD, QList<Para> &paras, QString sExSW)
    {
        try
        {
            bool bR_F = m_Reader.SendAPDU(sCMD.trimmed());

            this->Response = m_Reader.Response();
            this->SW = m_Reader.SS();
            if (bR_F == false)
            {
                this->Response = "NO RESPONSE";
                Para para1 = Para("LAST", this->Response);
                BOP.ParaUpdate(paras, para1);
            }

            if (m_Reader.Response() != "")
            {
                sLOG = "|Command:" + sCMD + "|Response:" + m_Reader.Response() + "|SW:" + m_Reader.SS();
            }
            else
            {
                sLOG = "|Command:" + sCMD + "|SW:" + m_Reader.SS();
            }

            if (!bR_F)
            {
                throw std::runtime_error(QString("指令失败 %1").arg(sLOG).toStdString());
            }
            if (sExSW == "") // 如果赋空值，代表不判断返回结果
            {
                return;
            }
            else
            {
                if (this->SW != sExSW)
                {
                    sLOG = "|Command:" + sCMD + "|SW:" + m_Reader.SS();
                    throw std::runtime_error(QString("指令失败 %1").arg(sLOG).toStdString());
                }
            }
        }
        catch (...)
        {
            throw std::runtime_error(QString("指令失败 %1").arg(sLOG).toStdString());
        }
    }

}
